/* eslint-disable no-unused-vars */
// @flow
// 'use strict';
/**
 * 拦截器的思想就是一个U形状调用，每一个任务都有接受参数，跟返回结果的功能
 * 但是每个任务的结果不是立马返回，类似 A->B-C  返回的时候 C->B->A  最终的结果会在最上层的调用层返回
 * 下面RealTaskChain 就是调用链的入口
 * RealTaskChain 维护了一个责任链的集合和索引，每次传递的时候，会new一个自己对象，然后每一个任务都是在
 * RealTaskChain里面执行的，执行交给下面一个，但这个时候最终的结果还没返回，可以传递下去，不传递就是立马返回
 *
 * 调用的感觉就是==>A(B(C())) 如何做到的就是责任链的集合跟索引
 */

import Logger from "./logger";
import {
    getBrowserClientInfo
} from "../lib/tool";
import {
    IRtcClient
} from "../lib/irtcScript";
import {
    addStreamToMix,
    startRecord
} from "../lib/api";
import {client} from '../lib/client';

/**
 * 任务拦截器的数据返回包装类
 */
class Response {
    constructor(code, message) {
        this.code = code;
        this.message = message;
    }
}

/**
 * 任务拦截器接受参数的封装类，也用来传递参数
 */
class Request {
    constructor(data) {
        this.data = data;
    }
}

/**
 * 责任链基类，不好写成java那样的接口，空实现的函数
 * 这里类似Java 接口，先定义好基础的方法
 */
class Chain {
    constructor(mInterceptors, index, request) {}

    /**
     * 读取当前的request 做个只是一个思想，通过方法读取变量，不直接读变量
     * @returns {null}
     */
    request() {
        return null;
    }

    /**
     * 处理责任链逻辑
     * @returns {null}
     */
    proceed(request) {
        return null;
    }
}

/**
 * 任务拦截器的基类，这个在java中是一个接口,
 */
class TaskInterceptor {
    /**
     *
     * @param chain Chain 对象
     * @returns 返回是一个 Response 对象
     */
    intercept(chain) {
        return null;
    }
}

/**
 * 责任链控制类
 */
class RealTaskChain extends Chain {
    /**
     * 拦截器就是可以看作一个个的任务
     * @param interceptors
     * @param index 当前拦截器的索引
     * @param request 每个拦截器收到上一个拦截器的入参
     */
    constructor(interceptors, index, request) {
        super(interceptors, index, request);
        this.mInteceptors = interceptors;
        this.mIndex = index;
        this.mRequest = request;
    }
    proceed(request) {
        //当前索引超出拦截器集合的范围
        if (this.mIndex > this.mInteceptors.length) {
            return;
        }
        //获取下一个拦截器
        let next = new RealTaskChain(this.mInteceptors, this.mIndex + 1, request);
        //执行下一个拦截器并返回结果
        return this.mInteceptors[this.mIndex].intercept(next);
    }
    //获取当前拦截器的入参
    request() {
        return this.mRequest;
    }
}



class amsAnswerTask extends TaskInterceptor {
    intercept(chain) {
        let requestParameter = chain.request();
        let amsClient = requestParameter.amsClient;
        amsClient.answerCall(function (status, resp) {
            if (status === 'ok') {
                Logger.info(`answer call success,${resp},${new Date()}`);
                return chain.proceed(requestParameter); //参数直接传递给下一个任务
            } else {
                Logger.warning(`answer call failed,${resp},${new Date()}`);
                return new Response('100', `answer call failed,${resp}`);
            }
        })
    }
}


class ccsConnectTask extends TaskInterceptor {
    intercept(chain) {
        let requestParameter = chain.request();
        let ccsUrl = requestParameter.url;
        let accessToken = requestParameter.accesstoken;
        client.connect(ccsUrl, accessToken, (resp) => {
            Logger.info(`connect to ccs success,${new Date()},${resp}`);
            return chain.proceed(requestParameter); //参数直接传递给下一个任务
        }, (error) => {
            Logger.info(`connect to ccs error,${error},${new Date()}`);
            return new Response(`connect to ccs error,${error},${new Date()}`);
        });
    }
}


class ccsJoinSessionTask extends TaskInterceptor {
    intercept(chain) {
        let sessionId = '';
        let joinData = {
            media: 'video',
            userData: {
                skill: '',
                specifyAgent: ''
            },
            sessionId: sessionId,
            clientInfo: getBrowserClientInfo()
        };
        client.joinSession(joinData, (joinResult) => {
            Logger.info(`join session ${sessionId} success,${JSON.stringify(joinResult)},${new Date()}`);
        }, (error) => {
            Logger.info(`join session ${sessionId} error,${error},${new Date()}`);
        });
    }
}


let answerCallInterceptor = [new amsAnswerTask()];

let answerRequest = new Request('amsClient');
let answerTaskChain = new RealTaskChain(answerCallInterceptor, 0, answerRequest);
let response = answerTaskChain.proceed(answerRequest);
